<template>
    <div class="main">
        <div class="left header">
            <div class="but-item">
                <el-button
                    @click="runCase"
                    :loading="caseLoading"
                    type="success">
                    运行用例
                </el-button>
            </div>
            <div class="but-item">
                <el-button @click="closeSession" type="danger">
                    结束用例
                </el-button>
            </div>
            <div class="but-item">
                <el-button @click="downloadYaml" type="primary">
                    输出yaml
                </el-button>
            </div>

            <div class="but-item">
                <el-upload
                    :show-file-list="false"
                    :on-success="uploadSuccess"
                    :on-error="uploadError"
                    @click="changeUploadType(0)"
                    :action="baseUrl + '/uploadYaml'">
                    <el-button type="primary">导入yaml</el-button>
                </el-upload>
            </div>
            <div class="but-item">
                <el-upload
                    :show-file-list="false"
                    :on-success="uploadSuccess"
                    :on-error="uploadError"
                    @click="changeUploadType(1)"
                    :action="baseUrl + '/uploadYaml'">
                    <el-button type="primary">导入片段</el-button>
                </el-upload>
            </div>
            <div class="but-item">
                <el-button @click="logDrawer = true" type="primary">
                    查看日志
                </el-button>
            </div>
            <div class="but-item">
                <el-button type="primary" @click="jsonDrawer = true"
                    >jmespath调试</el-button
                >
            </div>
            <div class="but-item">
                <el-button type="primary" @click="configDrawer = true"
                    >工程配置</el-button
                >
            </div>
        </div>
        <el-collapse class="collapse-main">
            <div class="collapse-item">
                <div class="collapse-item-container">
                    <el-collapse-item :title="'Config: ' + config.name">
                        <div class="item">
                            <div class="title left">文件名:</div>
                            <el-input
                                v-model="fileName"
                                placeholder="用例名文件名">
                                <template #append>.yaml</template>
                            </el-input>
                        </div>
                        <div class="item">
                            <div class="title left">用例名:</div>
                            <el-input
                                v-model="config.name"
                                placeholder="用例名" />
                        </div>

                        <div class="item">
                            <div class="title left">base-url:</div>
                            <el-input
                                v-model="config.base_url"
                                placeholder="域名" />
                        </div>
                        <div class="item">
                            <div class="title left">HTTPS:</div>
                            <el-select
                                class="select-width"
                                v-model="config.verify"
                                placeholder="HTTPS验证">
                                <el-option
                                    v-for="item in isHttps"
                                    :key="item"
                                    :label="item"
                                    :value="item">
                                </el-option>
                            </el-select>
                        </div>
                        <div class="list">
                            <div class="left title">自定义属性</div>
                            <div
                                class="left li-item"
                                v-for="(attr, index) in config.customAttrList"
                                :key="index">
                                <li>
                                    <el-input
                                        v-model="attr.name"
                                        style="width: 150px"
                                        placeholder="属性名" />:
                                    <el-input
                                        v-model="attr.value"
                                        style="width: 240px; margin-right: 5px"
                                        placeholder="属性值" />
                                    <el-button
                                        v-if="
                                            index ==
                                            config.customAttrList.length - 1
                                        "
                                        type="primary"
                                        @click="addParam(config.customAttrList)"
                                        >添加</el-button
                                    >
                                    <el-button
                                        type="danger"
                                        @click="
                                            delParam(
                                                config.customAttrList,
                                                index
                                            )
                                        "
                                        >删除</el-button
                                    >
                                </li>
                            </div>
                            <el-button
                                class="left"
                                v-if="config.customAttrList.length == 0"
                                type="primary"
                                @click="addParam(config.customAttrList)"
                                >添加</el-button
                            >
                        </div>
                        <div class="list">
                            <div class="left title">参数化-列表</div>
                            <div
                                class="left li-item"
                                v-for="(param, index) in config.parameterList"
                                :key="index">
                                <li>
                                    <el-input
                                        v-model="param.name"
                                        style="width: 150px"
                                        placeholder="属性名" />:
                                    <el-input
                                        v-model="param.value"
                                        style="width: 240px; margin-right: 5px"
                                        placeholder="属性值" />
                                    <el-button
                                        v-if="
                                            index ==
                                            config.parameterList.length - 1
                                        "
                                        type="primary"
                                        @click="addParam(config.parameterList)"
                                        >添加</el-button
                                    >
                                    <el-button
                                        type="danger"
                                        @click="
                                            delParam(
                                                config.parameterList,
                                                index
                                            )
                                        "
                                        >删除</el-button
                                    >
                                </li>
                            </div>
                            <el-button
                                class="left"
                                v-if="config.parameterList.length == 0"
                                type="primary"
                                @click="addParam(config.parameterList)"
                                >添加</el-button
                            >
                        </div>

                        <div class="list">
                            <div class="left title">设置变量</div>
                            <div
                                class="left li-item"
                                v-for="(variable, index) in config.variableList"
                                :key="index">
                                <li>
                                    <el-input
                                        v-model="variable.name"
                                        style="width: 150px"
                                        placeholder="变量名" />:
                                    <el-input
                                        v-model="variable.value"
                                        style="width: 240px; margin-right: 5px"
                                        placeholder="变量值" />
                                    <el-button
                                        v-if="
                                            index ==
                                            config.variableList.length - 1
                                        "
                                        type="primary"
                                        @click="addParam(config.variableList)"
                                        >添加</el-button
                                    >
                                    <el-button
                                        type="danger"
                                        @click="
                                            delParam(config.variableList, index)
                                        "
                                        >删除</el-button
                                    >
                                </li>
                            </div>
                            <el-button
                                class="left"
                                v-if="config.variableList.length == 0"
                                type="primary"
                                @click="addParam(config.variableList)"
                                >添加</el-button
                            >
                        </div>
                        <div class="list">
                            <div class="left title">导出全局变量</div>
                            <div
                                class="left li-item"
                                v-for="(eName, index) in config.export"
                                :key="index">
                                <li>
                                    <el-input
                                        v-model="config.export[index]"
                                        style="width: 150px; margin-right: 5px"
                                        placeholder="变量名" />
                                    <el-button
                                        v-if="index == config.export.length - 1"
                                        type="primary"
                                        @click="addArr(config.export)"
                                        >添加</el-button
                                    >
                                    <el-button
                                        type="danger"
                                        @click="delParam(config.export, index)"
                                        >删除</el-button
                                    >
                                </li>
                            </div>
                            <el-button
                                class="left"
                                v-if="config.export.length == 0"
                                type="primary"
                                @click="addArr(config.export)"
                                >添加</el-button
                            >
                        </div>
                    </el-collapse-item>
                </div>
                <div class="button-top">
                    <div class="button-container">
                        <div class="checkbox">
                            <el-checkbox
                                @change="handleCheckAllChange"
                                v-model="checkAll"></el-checkbox>
                        </div>
                        <div class="but-item">
                            <el-button
                                :loading="runStepsStatus"
                                type="success"
                                @click="runSteps()"
                                >批量执行</el-button
                            >
                        </div>
                        <div class="but-item">
                            <el-button type="primary" @click="updateConfig()"
                                >更新配置</el-button
                            >
                        </div>
                    </div>
                </div>
            </div>
            <!-- 步骤 -->
            <div
                class="collapse-item"
                v-for="(step, index) in steps"
                @click="openStep($event, step)"
                :draggable="step.isDraggable"
                @dragstart="dragStart(index)"
                @dragend="dragEnd"
                @dragover.prevent="dragOver(index)"
                :key="index">
                <div class="collapse-item-container">
                    <el-collapse-item
                        :name="index"
                        :title="'STEP' + (index + 1) + ': ' + step.name">
                        <div class="item">
                            <div class="title left">步骤名:</div>
                            <el-input
                                style="width: 500px"
                                v-model="step.name"
                                placeholder="步骤名" />
                        </div>
                        <div class="list">
                            <div class="left title">setup_hooks</div>
                            <div
                                class="left li-item"
                                v-for="(eName, index) in step.setup_hooks"
                                :key="index">
                                <li>
                                    <el-input
                                        v-model="step.setup_hooks[index]"
                                        style="width: 400px; margin-right: 5px"
                                        placeholder="hook函数" />
                                    <el-button
                                        v-if="
                                            index == step.setup_hooks.length - 1
                                        "
                                        type="primary"
                                        @click="addArr(step.setup_hooks)"
                                        >添加</el-button
                                    >
                                    <el-button
                                        type="danger"
                                        @click="
                                            delParam(step.setup_hooks, index)
                                        "
                                        >删除</el-button
                                    >
                                </li>
                            </div>
                            <el-button
                                class="left"
                                v-if="step.setup_hooks.length == 0"
                                type="primary"
                                @click="addArr(step.setup_hooks)"
                                >添加</el-button
                            >
                        </div>
                        <div class="list">
                            <div class="left title">teardown_hooks</div>
                            <div
                                class="left li-item"
                                v-for="(eName, index) in step.teardown_hooks"
                                :key="index">
                                <li>
                                    <el-input
                                        v-model="step.teardown_hooks[index]"
                                        style="width: 400px; margin-right: 5px"
                                        placeholder="hook函数" />
                                    <el-button
                                        v-if="
                                            index ==
                                            step.teardown_hooks.length - 1
                                        "
                                        type="primary"
                                        @click="addArr(step.teardown_hooks)"
                                        >添加</el-button
                                    >
                                    <el-button
                                        type="danger"
                                        @click="
                                            delParam(step.teardown_hooks, index)
                                        "
                                        >删除</el-button
                                    >
                                </li>
                            </div>
                            <el-button
                                class="left"
                                v-if="step.teardown_hooks.length == 0"
                                type="primary"
                                @click="addArr(step.teardown_hooks)"
                                >添加</el-button
                            >
                        </div>
                        <div class="list">
                            <div class="title left">设置变量</div>
                            <div
                                class="left li-item"
                                v-for="(variable, index) in step.variableList"
                                :key="index">
                                <li>
                                    <el-input
                                        v-model="variable.name"
                                        style="width: 150px"
                                        placeholder="变量名" />:
                                    <el-input
                                        v-model="variable.value"
                                        style="width: 240px; margin-right: 5px"
                                        placeholder="变量值" />
                                    <el-button
                                        v-if="
                                            index ==
                                            step.variableList.length - 1
                                        "
                                        type="primary"
                                        @click="addParam(step.variableList)"
                                        >添加</el-button
                                    >
                                    <el-button
                                        type="danger"
                                        @click="
                                            delParam(step.variableList, index)
                                        "
                                        >删除</el-button
                                    >
                                </li>
                            </div>
                            <el-button
                                class="left"
                                v-if="step.variableList.length == 0"
                                type="primary"
                                @click="addParam(step.variableList)"
                                >添加</el-button
                            >
                        </div>
                        <div class="item" style="flex-direction: column">
                            <div class="title left">请求配置:</div>

                            <div class="item li-item">
                                <div class="title left">请求方法:</div>
                                <el-select
                                    class="select-width"
                                    v-model="step.request.method"
                                    placeholder="请求方法">
                                    <el-option
                                        v-for="item in MethodOptions"
                                        :key="item"
                                        :label="item"
                                        :value="item">
                                    </el-option>
                                </el-select>
                            </div>
                            <div class="item">
                                <div class="title left">接口url:</div>
                                <el-input
                                    v-model="step.request.url"
                                    placeholder="url" />
                            </div>
                            <div class="list">
                                <div class="title left">headers</div>
                                <div
                                    class="left li-item"
                                    v-for="(header, index) in step.request
                                        .headerList"
                                    :key="index">
                                    <li>
                                        <el-input
                                            v-model="header.name"
                                            style="width: 150px"
                                            placeholder="变量名" />:
                                        <el-input
                                            v-model="header.value"
                                            style="
                                                width: 240px;
                                                margin-right: 5px;
                                            "
                                            placeholder="变量值" />
                                        <el-button
                                            v-if="
                                                index ==
                                                step.request.headerList.length -
                                                    1
                                            "
                                            type="primary"
                                            @click="
                                                addParam(
                                                    step.request.headerList
                                                )
                                            "
                                            >添加</el-button
                                        >
                                        <el-button
                                            type="danger"
                                            @click="
                                                delParam(
                                                    step.request.headerList,
                                                    index
                                                )
                                            "
                                            >删除</el-button
                                        >
                                    </li>
                                </div>
                                <el-button
                                    class="left"
                                    v-if="step.request.headerList.length == 0"
                                    type="primary"
                                    @click="addParam(step.request.headerList)"
                                    >添加</el-button
                                >
                            </div>
                            <div class="list">
                                <div class="title left">cookies</div>
                                <div
                                    class="left li-item"
                                    v-for="(cookie, index) in step.request
                                        .cookieList"
                                    :key="index">
                                    <li>
                                        <el-input
                                            v-model="cookie.name"
                                            style="width: 150px"
                                            placeholder="变量名" />:
                                        <el-input
                                            v-model="cookie.value"
                                            style="
                                                width: 240px;
                                                margin-right: 5px;
                                            "
                                            placeholder="变量值" />
                                        <el-button
                                            v-if="
                                                index ==
                                                step.request.cookieList.length -
                                                    1
                                            "
                                            type="primary"
                                            @click="
                                                addParam(
                                                    step.request.cookieList
                                                )
                                            "
                                            >添加</el-button
                                        >
                                        <el-button
                                            type="danger"
                                            @click="
                                                delParam(
                                                    step.request.cookieList,
                                                    index
                                                )
                                            "
                                            >删除</el-button
                                        >
                                    </li>
                                </div>
                                <el-button
                                    class="left"
                                    v-if="step.request.cookieList.length == 0"
                                    type="primary"
                                    @click="addParam(step.request.cookieList)"
                                    >添加</el-button
                                >
                            </div>
                            <div id="requestData">
                                <el-radio-group v-model="step.paramRadio">
                                    <el-radio :value="1">表单</el-radio>
                                    <el-radio :value="2">JSON</el-radio>
                                    <el-radio :value="3">params</el-radio>
                                </el-radio-group>
                                <div class="params" v-if="step.paramRadio == 1">
                                    <div
                                        class="left li-item"
                                        v-for="(data, index) in step.request
                                            .dataList"
                                        :key="index">
                                        <el-input
                                            v-model="data.name"
                                            style="width: 150px"
                                            placeholder="变量名" />:
                                        <el-input
                                            v-model="data.value"
                                            style="
                                                width: 240px;
                                                margin-right: 5px;
                                            "
                                            placeholder="变量值" />
                                        <el-button
                                            v-if="
                                                index ==
                                                step.request.dataList.length - 1
                                            "
                                            type="primary"
                                            @click="
                                                addParam(step.request.dataList)
                                            "
                                            >添加</el-button
                                        >
                                        <el-button
                                            type="danger"
                                            @click="
                                                delParam(
                                                    step.request.dataList,
                                                    index
                                                )
                                            "
                                            >删除</el-button
                                        >
                                    </div>
                                    <el-button
                                        class="left"
                                        v-if="step.request.dataList.length == 0"
                                        type="primary"
                                        @click="addParam(step.request.dataList)"
                                        >添加</el-button
                                    >
                                </div>
                                <div v-if="step.paramRadio == 2" id="json">
                                    <div
                                        style="
                                            display: flex;
                                            margin-bottom: 15px;
                                        ">
                                        <div
                                            class="but-item"
                                            style="width: 150px">
                                            <el-select
                                                v-model="aceConfig.theme"
                                                class="m-2"
                                                placeholder="Select">
                                                <el-option
                                                    v-for="item in aceConfig.arr"
                                                    :key="item"
                                                    :label="item"
                                                    :value="item" />
                                            </el-select>
                                        </div>
                                        <div class="but-item">
                                            <el-button
                                                @click="formatStepJson(step)"
                                                >格式化</el-button
                                            >
                                        </div>
                                        <div class="but-item">
                                            <el-button
                                                @click="compressStepJson(step)"
                                                >压缩</el-button
                                            >
                                        </div>
                                    </div>

                                    <v-ace-editor
                                        v-model:value="step.request.json"
                                        @init="formatStepJson"
                                        lang="json"
                                        :theme="aceConfig.theme"
                                        :options="aceConfig.options"
                                        :readonly="aceConfig.readOnly"
                                        style="height: 300px; width: 650px"
                                        class="ace-editor" />
                                </div>
                                <div class="params" v-if="step.paramRadio == 3">
                                    <div
                                        class="left li-item"
                                        v-for="(param, index) in step.request
                                            .paramList"
                                        :key="index">
                                        <el-input
                                            v-model="param.name"
                                            style="width: 150px"
                                            placeholder="变量名" />:
                                        <el-input
                                            v-model="param.value"
                                            style="
                                                width: 240px;
                                                margin-right: 5px;
                                            "
                                            placeholder="变量值" />
                                        <el-button
                                            v-if="
                                                index ==
                                                step.request.paramList.length -
                                                    1
                                            "
                                            type="primary"
                                            @click="
                                                addArr(step.request.paramList)
                                            "
                                            >添加</el-button
                                        >
                                        <el-button
                                            type="danger"
                                            @click="
                                                delParam(
                                                    step.request.paramList,
                                                    index
                                                )
                                            "
                                            >删除</el-button
                                        >
                                    </div>
                                    <el-button
                                        class="left"
                                        v-if="
                                            step.request.paramList.length == 0
                                        "
                                        type="primary"
                                        @click="addArr(step.request.paramList)"
                                        >添加</el-button
                                    >
                                </div>
                            </div>
                        </div>

                        <div class="list">
                            <div class="title left">参数提取</div>
                            <div
                                class="left li-item"
                                v-for="(extract, index) in step.extractList"
                                :key="index">
                                <li>
                                    <el-input
                                        v-model="extract.value"
                                        style="width: 240px"
                                        placeholder="jmes_path" />:
                                    <el-input
                                        v-model="extract.name"
                                        style="width: 150px; margin-right: 5px"
                                        placeholder="name" />
                                    <el-button
                                        v-if="
                                            index == step.extractList.length - 1
                                        "
                                        type="primary"
                                        @click="addParam(step.extractList)"
                                        >添加</el-button
                                    >
                                    <el-button
                                        type="danger"
                                        @click="
                                            delParam(step.extractList, index)
                                        "
                                        >删除</el-button
                                    >
                                </li>
                            </div>
                            <el-button
                                class="left"
                                v-if="step.extractList.length == 0"
                                type="primary"
                                @click="addParam(step.extractList)"
                                >添加</el-button
                            >
                        </div>
                        <div class="list">
                            <div class="title left">断言</div>
                            <div
                                class="left li-item"
                                v-for="(validate, index) in step.validateList"
                                :key="index">
                                <el-select
                                    style="width: 130px"
                                    v-model="validate.funcName"
                                    placeholder="断言方法">
                                    <el-option
                                        v-for="item in ValidateFunc"
                                        :key="item"
                                        :label="item"
                                        :value="item">
                                    </el-option>
                                </el-select>
                                <el-input
                                    v-model="validate.actual"
                                    style="width: 120px"
                                    placeholder="实际值" />
                                <el-input
                                    v-model="validate.expected"
                                    style="width: 120px"
                                    placeholder="预期值" />
                                <el-input
                                    v-model="validate.msg"
                                    style="width: 150px"
                                    placeholder="失败提示" />
                                <el-button
                                    v-if="index == step.validateList.length - 1"
                                    type="primary"
                                    @click="addValidate(step.validateList)"
                                    >添加</el-button
                                >
                                <el-button
                                    type="danger"
                                    @click="delParam(step.validateList, index)"
                                    >删除</el-button
                                >
                            </div>
                            <el-button
                                class="left"
                                v-if="step.validateList.length == 0"
                                type="primary"
                                @click="addValidate(step.validateList)"
                                >添加</el-button
                            >
                        </div>
                    </el-collapse-item>
                </div>
                <div class="button-top">
                    <div class="button-container">
                        <div class="checkbox">
                            <el-checkbox v-model="step.checked"></el-checkbox>
                        </div>
                        <div class="but-item">
                            <el-button
                                type="success"
                                :loading="step.status == 'running'"
                                @click="runStep(step, true)"
                                >运行</el-button
                            >
                        </div>
                        <div class="but-item" v-if="index == steps.length - 1">
                            <el-button type="primary" @click="addStep(steps)"
                                >添加</el-button
                            >
                        </div>
                        <div class="but-item">
                            <el-button
                                type="primary"
                                @click="copyStep(steps, index)"
                                >复制</el-button
                            >
                        </div>
                        <div class="but-item">
                            <el-popconfirm
                                confirm-button-text="是"
                                cancel-button-text="否"
                                @confirm="delParam(steps, index)"
                                icon-color="#626AEF"
                                title="是否删除此步骤？">
                                <template #reference>
                                    <el-button type="danger">删除</el-button>
                                </template>
                            </el-popconfirm>
                        </div>
                        <div v-if="step.status == 'success'" class="but-item">
                            <svg
                                t="1716087703819"
                                class="icon"
                                viewBox="0 0 1024 1024"
                                version="1.1"
                                p-id="2295"
                                width="25"
                                height="25">
                                <path
                                    d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m-74.965333 550.4L346.453333 545.152a42.666667 42.666667 0 1 0-60.330666 60.330667l120.704 120.704a42.666667 42.666667 0 0 0 60.330666 0l301.653334-301.696a42.666667 42.666667 0 1 0-60.288-60.330667l-271.530667 271.488z"
                                    fill="#52C41A"
                                    p-id="2296"></path>
                            </svg>
                        </div>
                        <div v-if="step.status == 'error'" class="but-item">
                            <svg
                                t="1716087971311"
                                class="icon"
                                viewBox="0 0 1024 1024"
                                version="1.1"
                                p-id="5156"
                                width="25"
                                height="25">
                                <path
                                    d="M512.8 512m-423 0a423 423 0 1 0 846 0 423 423 0 1 0-846 0Z"
                                    fill="#FF7575"
                                    p-id="5157"></path>
                                <path
                                    d="M481.3 590.7c5.3 15.8 15.8 26.2 31.5 26.2 15.8 0 26.2-10.5 31.5-26.2l21-288.7c0-31.5-26.2-52.5-52.5-52.5-31.5 0-52.5 26.2-52.5 57.8l21 283.4z m31.5 78.8c-31.5 0-52.5 21-52.5 52.5s21 52.5 52.5 52.5 52.5-21 52.5-52.5-21-52.5-52.5-52.5z m0 0"
                                    fill="#FFFFFF"
                                    p-id="5158"></path>
                            </svg>
                        </div>
                    </div>
                </div>
            </div>
        </el-collapse>
        <el-drawer
            v-model="logDrawer"
            title="日志"
            size="50%"
            :direction="logDirection"
            :before-close="handleClose">
            <div class="logs" v-html="formattedLogs"></div>
        </el-drawer>
        <el-drawer
            v-model="jsonDrawer"
            size="50%"
            title="jmespath调试"
            :direction="jsonDirection"
            :before-close="handleClose">
            <div id="json-debug">
                <div style="width: 500px">
                    <div style="display: flex; margin-bottom: 5px">
                        <div class="but-item" style="width: 150px">
                            <el-select
                                v-model="aceConfig.theme"
                                class="m-2"
                                placeholder="Select">
                                <el-option
                                    v-for="item in aceConfig.arr"
                                    :key="item"
                                    :label="item"
                                    :value="item" />
                            </el-select>
                        </div>
                        <div class="but-item">
                            <el-button @click="formatJson(debugJson)"
                                >格式化</el-button
                            >
                        </div>
                        <div class="but-item">
                            <el-button @click="compressJson(debugJson)"
                                >压缩</el-button
                            >
                        </div>
                        <div class="but-item">
                            <el-button @click="copyText(jmespathStr)"
                                >复制文本</el-button
                            >
                        </div>
                    </div>
                    <div style="margin-bottom: 15px">
                        <el-input
                            v-model="jmespathStr"
                            placeholder="jmes_path" />
                    </div>
                </div>
                <v-ace-editor
                    v-model:value="debugJson"
                    lang="json"
                    :theme="aceConfig.theme"
                    :options="aceConfig.options"
                    :readonly="aceConfig.readOnly"
                    style="height: 300px; width: 650px; margin-bottom: 10px"
                    class="ace-editor" />
                <div class="but-item left">结果：</div>
                <v-ace-editor
                    v-model:value="searchResult"
                    lang="json"
                    :theme="aceConfig.theme"
                    :options="aceConfig.options"
                    :readonly="true"
                    style="height: 300px; width: 650px"
                    class="ace-editor" />
            </div>
        </el-drawer>
        <el-drawer
            v-model="configDrawer"
            size="50%"
            title="工程配置"
            :direction="jsonDirection"
            :before-close="handleClose">
            <div id="config">
                <div style="width: 500px">
                    <div style="margin-bottom: 20px">
                        <div>
                            <div class="title left">工程目录:</div>
                            <el-input
                                v-model="workPath"
                                style="width: 500px; margin-bottom: 10px"
                                placeholder="工程根目录：/testcases" />
                        </div>
                        <div>
                            <div class="title left">用例输出路径:</div>
                            <el-input
                                v-model="yamlOutPath"
                                style="width: 500px; margin-bottom: 10px"
                                placeholder="用例输出路径：/testcases/login/" />
                        </div>
                        <div>
                            <div class="title left" style="width: 150px">
                                python用例执行路径:
                            </div>
                            <el-input
                                v-model="caseOutPath"
                                style="width: 500px; margin-bottom: 10px"
                                placeholder="用例执行路径：/testcases/login/" />
                        </div>
                        <div>
                            <div class="title left">编译命令:</div>
                            <el-input
                                v-model="compileCommand"
                                style="width: 500px; margin-bottom: 10px"
                                placeholder="编译命令：httprunner make" />
                        </div>
                        <div class="left but-item">
                            <el-button
                                :disabled="serverStauts == 'running'"
                                type="primary"
                                :loading="serverStauts == 'starting'"
                                @click="runServe()"
                                >启动服务</el-button
                            >
                            <el-button
                                type="danger"
                                :disabled="serverStauts == 'stop'"
                                @click="stopServer()"
                                >关闭服务</el-button
                            >
                        </div>
                    </div>
                </div>
            </div>
        </el-drawer>
    </div>
</template>

<script setup>
import { ref, reactive, watch, computed, onMounted, nextTick } from "vue";
import axios from "axios";
import { VAceEditor } from "vue3-ace-editor";
import jmespath from "jmespath";
import "ace-builds/webpack-resolver";
import "ace-builds/src-noconflict/mode-json";
import "ace-builds/src-noconflict/theme-chrome";
import "ace-builds/src-noconflict/ext-language_tools";

const popupError = (msg) => {
    ElMessage({
        message: msg.slice(0, 200),
        type: "error",
        plain: true,
        duration: 1500,
    });
};

const popupSuss = (msg) => {
    ElMessage({
        message: msg,
        type: "success",
        duration: 1500,
    });
};

/**
 * 将数据存储在本地缓存中
 *
 * @param key 缓存键
 * @param value 缓存值
 */
const storeInCache = (key, value) => {
    localStorage.setItem(key, JSON.stringify(value));
};

/**
 * 从本地缓存中读取配置信息
 *
 * @param key 配置信息对应的key
 * @returns 解析后的配置对象，若未找到或解析失败则返回null
 */
const readFromCache = (key) => {
    const cachedConfigString = localStorage.getItem(key);

    let cachedConfig;
    try {
        cachedConfig = JSON.parse(cachedConfigString);
    } catch (error) {
        console.error("Failed to parse cached config:", error);
        cachedConfig = null;
    }

    // 返回解析后的对象，或者在没有找到/解析失败时返回null
    return cachedConfig;
};

const caseLoading = ref(false);
const logDirection = ref("rtl");
const jsonDirection = ref("rtl");

const fileName = ref("");
let fileNameCache = readFromCache("fileName");
if (fileNameCache) {
    fileName.value = fileNameCache;
}
// 监听workPath变化，存储到缓存中
watch(
    fileName,
    (newValue, oldValue) => {
        // 存储变化后的整个config对象到缓存中
        storeInCache("fileName", newValue);
    },
    { deep: true } // 深度监听对象内部的变化
);

const workPath = ref("");
let workPathCache = readFromCache("workPath");
if (workPathCache) {
    workPath.value = workPathCache;
}

// 监听workPath变化，存储到缓存中
watch(
    workPath,
    (newValue, oldValue) => {
        // 存储变化后的整个config对象到缓存中
        storeInCache("workPath", newValue);
    },
    { deep: true } // 深度监听对象内部的变化
);

const yamlOutPath = ref("");

let yamlOutPathCache = readFromCache("yamlOutPath");
if (yamlOutPathCache) {
    yamlOutPath.value = yamlOutPathCache;
}

// 监听config变化，存储到缓存中
watch(
    yamlOutPath,
    (newValue, oldValue) => {
        // 存储变化后的整个config对象到缓存中
        storeInCache("yamlOutPath", newValue);
    },
    { deep: true } // 深度监听对象内部的变化
);

const caseOutPath = ref("");

let caseOutPathCache = readFromCache("caseOutPath");
if (caseOutPathCache) {
    caseOutPath.value = caseOutPathCache;
}

// 监听config变化，存储到缓存中
watch(
    caseOutPath,
    (newValue, oldValue) => {
        // 存储变化后的整个config对象到缓存中
        storeInCache("caseOutPath", newValue);
    },
    { deep: true } // 深度监听对象内部的变化
);

const compileCommand = ref("");
let compileCommandCache = readFromCache("compileCommand");
if (compileCommandCache) {
    compileCommand.value = compileCommandCache;
}

// 监听config变化，存储到缓存中
watch(
    compileCommand,
    (newValue, oldValue) => {
        // 存储变化后的整个config对象到缓存中
        storeInCache("compileCommand", newValue);
    },
    { deep: true } // 深度监听对象内部的变化
);

const baseUrl = ref("http://localhost:5000");

const copyText = async (Msg) => {
    try {
        //复制
        window.ipcRenderer.send("appToMain", {
            cmd: "copy",
            text: Msg,
        });
        popupSuss("复制成功");
    } catch (e) {
        //复制失败
        console.error(e);
        popupError(e);
    }
};

// watch(debugJson, (newValue) => {

//     jmespathData.oldData = newValue;
// });

const serverStauts = ref("stop");

watch(serverStauts, (newValue) => {
    if (newValue == "running") {
        popupSuss("服务启动成功");
    } else if (serverStauts == "stop") {
        popupSuss("服务已停止");
    }
});

// 渲染进程发送事件===这个可以放到一个点击事件里面去触发
const debugJson = ref("");
const searchResult = ref("");
const jmespathStr = ref("");
watch(jmespathStr, (newValue, oldValue) => {
    if (newValue != "") {
        try {
            let result = jmespath.search(JSON.parse(debugJson.value), newValue);
            if (result == null) {
                return;
            }
            searchResult.value = JSON.stringify(result, null, 4);
        } catch (e) {}
    }
});

//配置信息
const config = ref({
    name: "",
    base_url: "",
    verify: false,
    parameterList: [],
    customAttrList: [],
    variableList: [],
    export: [],
});

// 读取config缓存
let conf = readFromCache("config");
if (conf) {
    config.value = conf;
}

// 监听config变化，存储到缓存中
watch(
    config,
    (newValue, oldValue) => {
        // 存储变化后的整个config对象到缓存中
        storeInCache("config", newValue);
    },
    { deep: true } // 深度监听对象内部的变化
);

// 用例请求方法选项
const MethodOptions = ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"];

//是否严重https选项
const isHttps = [true, false];

//断言方法选项
const ValidateFunc = [
    "eq",
    "ne",
    "gt",
    "lt",
    "le",
    "ge",
    "ne",
    "str_eq",
    "len_eq",
    "len_gt",
    "len_ge",
    "len_lt",
    "len_le",
    "contains",
    "contained_by",
    "type_match",
    "regex_match",
    "startswith",
    "endswith",
];

// 测试步骤初始配置
const steps = ref([
    {
        name: "",
        setup_hooks: [],
        request: {
            url: "",
            method: "POST",
            headerList: [],
            cookieList: [],
            paramList: [{ name: "", value: "" }],
            dataList: [{ name: "", value: "" }],
            json: "",
        },
        teardown_hooks: [],
        variableList: [],
        extractList: [],
        validateList: [],
        paramRadio: 2,
        status: "ready", // 状态  运行中 running  错误 error 成功 success 准备好 ready
        isDraggable: true,
        checked: false,
    },
]);

// 读取步骤缓存
let stepList = readFromCache("steps");
if (stepList) {
    steps.value = stepList;
}

// 监听steps变化，存储到缓存中
watch(
    steps,
    (newSteps, oldValue) => {
        const areAllCheckboxesTrue = newSteps.every(
            (step) => step.checked === true
        );
        checkAll.value = areAllCheckboxesTrue;
        // 存储变化后的整个config对象到缓存中
        for (let i = 0; i < newSteps.length; i++) {
            if (newSteps[i].isDraggable == undefined) {
                newSteps[i].isDraggable = true;
            }
            if (newSteps[i].status == undefined) {
                newSteps[i].status = "ready";
            }
            if (newSteps[i].checked == undefined) {
                newSteps[i].checked = false;
            }
        }
        storeInCache("steps", newSteps);
    },
    { deep: true } // 深度监听对象内部的变化
);

const aceConfig = reactive({
    lang: "json", //解析json
    theme: "ambiance", //主题
    arr: [
        /*所有主题*/
        "ambiance",
        "chaos",
        "chrome",
        "clouds",
        "clouds_midnight",
        "cobalt",
        "crimson_editor",
        "dawn",
        "dracula",
        "dreamweaver",
        "eclipse",
        "github",
        "gob",
        "gruvbox",
        "idle_fingers",
        "iplastic",
        "katzenmilch",
        "kr_theme",
        "kuroir",
        "merbivore",
        "merbivore_soft",
        "monokai",
        "mono_industrial",
        "pastel_on_dark",
        "solarized_dark",
        "solarized_light",
        "sqlserver",
        "terminal",
        "textmate",
        "tomorrow",
        "tomorrow_night",
        "tomorrow_night_blue",
        "tomorrow_night_bright",
        "tomorrow_night_eighties",
        "twilight",
        "vibrant_ink",
        "xcode",
    ],
    readOnly: false, //是否只读
    options: {
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true,
        tabSize: 2,
        showPrintMargin: false,
        fontSize: 13,
    },
});

// 监听主题变化，存储到缓存中
const defTheme = ref("chrome");
let cacheTheme = readFromCache("theme");
if (cacheTheme) {
    aceConfig.theme = cacheTheme;
}

watch(
    () => aceConfig.theme, // 监听这个getter函数返回的值
    (newValue, oldValue) => {
        storeInCache("theme", newValue);
    },
    { immediate: true } // 立即执行一次回调函数，打印初始值
);

/**
 * 关闭日志抽屉
 *
 * @param done 关闭回调函数
 * @returns 无返回值
 */
const handleClose = (done) => {
    done();
};

// 侧边栏抽屉开关
const logDrawer = ref(false);
const jsonDrawer = ref(false);
const configDrawer = ref(false);

//日志主体
let responseBody = ref("");

// 格式化为彩色日志
const formattedLogs = computed(() => {
    // 初始化一个空数组来保存日志条目
    let logEntries = [];
    let currentLog = "";
    if (responseBody.value == "" || responseBody.value == undefined) {
        return "";
    }
    // 遍历日志数据的每一行
    console.log(responseBody.value, "body");
    for (const line of responseBody.value.trim().split("\n")) {
        // 检查当前行是否包含时间戳
        const timestampMatch = line.match(
            /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})/
        );
        if (timestampMatch) {
            // 如果找到时间戳，且当前日志不为空，则将其添加到日志条目数组中
            if (currentLog) {
                logEntries.push(currentLog);
            }
            // 重置当前日志内容，开始新的日志条目
            currentLog = line;
        } else {
            // 如果没有找到时间戳，则将当前行追加到当前日志条目中
            currentLog += "\n" + line;
        }
    }

    // 检查最后一个日志条目是否已添加到数组中（如果有的话）
    if (currentLog) {
        logEntries.push(currentLog);
    }
    let html = "";
    for (const log of logEntries) {
        const [timestamp, level, message] = log.split(" | ");
        const levelClass = `log-${level?.toLowerCase()}`;

        // 将消息内容中的换行符替换为 HTML 的换行标签 <br>

        // 为每个日志条目构建 HTML 字符串
        let tagName = "div";
        if (message && message.includes("run step begin")) {
            tagName = "h3";
        }
        if (log.includes("case run count")) {
            html += `<h2>${log}</h2>`;
        }
        if (message) {
            html += `<${tagName}><span class="timestamp">${timestamp}</span> | <span class="${levelClass}">${level}</span> | <span class="${levelClass}">${message}</span></${tagName}>\n`;
        }
    }

    return html;
});

/**
 * 打开步骤
 * 打开步骤后，不允许拖拽
 * @param event 事件对象
 * @param step 步骤对象
 * @returns 无返回值
 */
const openStep = (event, step) => {
    let targetEl = event.target;
    let classArray = Array.from(targetEl.classList);
    if (
        targetEl.tagName == "BUTTON" &&
        targetEl.id &&
        targetEl.id.includes("el-collapse-head")
    ) {
        formatStepJson(step);
        if (classArray.includes("is-active")) {
            step.isDraggable = false;
        } else {
            step.isDraggable = true;
        }
    }
};

// 拖拽相关变量
const dragIndex = ref(null);
let targetIndex = ref(null); // 目标位置的索引

// 拖拽开始时的处理
const dragStart = (index) => {
    dragIndex.value = index;
    targetIndex.value = null; // 重置目标位置索引
};

// 拖拽过程中的处理
const dragOver = (index) => {
    if (dragIndex.value !== null && dragIndex.value !== index) {
        targetIndex.value = index; // 更新目标位置索引
    }
};
// 拖拽结束时的处理（释放鼠标）
const dragEnd = () => {
    if (dragIndex.value !== null && targetIndex.value !== null) {
        // 获取拖拽元素和目标位置
        const dragItem = steps.value.splice(dragIndex.value, 1)[0]; // 从原位置移除拖拽元素
        steps.value.splice(targetIndex.value, 0, dragItem); // 在目标位置插入拖拽元素
        dragIndex.value = null; // 重置拖拽索引
        targetIndex.value = null; // 重置目标位置索引
    }
};

/**
 * 格式化Step JSON字符串
 *
 * @param step 步骤对象
 * @returns 无返回值
 */
const formatStepJson = (step) => {
    if (!step.request?.json) {
        return;
    }
    try {
        step.request.json = JSON.stringify(
            JSON.parse(step.request.json),
            null,
            2
        );
    } catch (e) {
        popupError(e);
    }
};

/**
 * 压缩Step JSON字符串
 *
 * @param step 请求步骤对象
 * @returns 无返回值
 */
const compressStepJson = (step) => {
    try {
        if (step.request.json == "") {
            return;
        }
        step.request.json = JSON.stringify(JSON.parse(step.request.json));
    } catch (e) {
        popupError(e);
    }
};

/**
 * 格式化 JSON字符串
 *
 * @param step 步骤对象
 * @returns 无返回值
 */
const formatJson = (json) => {
    try {
        debugJson.value = JSON.stringify(JSON.parse(json), null, 2);
    } catch (e) {
        popupError(e);
    }
};

/**
 * 压缩 JSON字符串
 *
 * @param step 请求步骤对象
 * @returns 无返回值
 */
const compressJson = (json) => {
    try {
        debugJson.value = JSON.stringify(JSON.parse(json));
    } catch (e) {
        popupError(e);
    }
};

const uploadType = ref(0);
const changeUploadType = (type) => {
    uploadType.value = type;
};
/**
 * 上传成功回调函数
 *
 * @param response 上传成功后的响应数据
 * @returns 无返回值
 */
const uploadSuccess = (response) => {
    let data = response.data;
    fileName.value = data.fileName.replace(".yaml", "");
    if (data.config && uploadType.value == 0) {
        config.value = data.config;
    }
    if (data.teststeps) {
        if (uploadType.value == 0) {
            steps.value = data.teststeps;
        } else {
            data.teststeps.forEach((step) => {
                steps.value.push(step);
            });
        }
    } else {
        popupError("teststeps 节点数据为空");
    }

    popupSuss("上传成功");
};

/**
 * 上传文件失败回调函数
 *
 * @param err 错误对象
 * @returns 无返回值
 */
const uploadError = (err) => {
    popupError("yaml格式不正确, 或服务端未启动 请检查！");
};

async function sendRequest(url, method, data = null, headers = {}) {
    try {
        const response = await axios({
            url: url,
            method: method,
            data: data,
            headers: headers,
        });

        if (response.status >= 200 && response.status < 300) {
            return response.data; // 返回请求成功的数据
        } else {
            popupError(response.data.message);
        }
    } catch (error) {
        console.error("Error sending request:", error);
        popupError("请确认是否启动服务");
        throw error; // 重新抛出错误，以便在调用处处理
    }
}

/**
 * 执行用例步骤
 *
 * @param step 步骤对象
 * @returns 无
 */
const runStep = async (step, isOpenLog) => {
    if (serverStauts.value != "running") {
        popupError("请确认是否启动服务");
        configDrawer.value = true;
        return;
    }
    if (isOpenLog) {
        steps.value.forEach((step) => {
            step.status = "ready";
        });
    }

    step.status = "running";
    let responseData = {};
    let msg = checkCase(step);
    if (msg != "") {
        popupError(msg);
        step.status = "ready";
        responseData.status = "error";
        return responseData;
    }
    let data = {
        step: step,
        config: config.value,
    };
    try {
        responseData = await sendRequest(
            `${baseUrl.value}/runstep`,
            "POST",
            data,
            { "Content-Type": "application/json" }
        );
        if (isOpenLog) {
            logDrawer.value = true;
            responseBody.value = responseData.logs;
        }
        if (responseData.status == "success") {
            step.status = "success";
        } else {
            step.status = "error";
        }
        return responseData;
    } catch (err) {
        step.status = "ready";
        responseData.status = "error";
    }
    return responseData;
};

const checkAll = ref(false);
const handleCheckAllChange = (val) => {
    steps.value.forEach((step) => {
        step.checked = val;
    });
};

const runStepsStatus = ref(false);

const runSteps = async () => {
    if (serverStauts.value != "running") {
        popupError("请确认是否启动服务");
        configDrawer.value = true;
        return;
    }
    responseBody.value = "";
    for (const step of steps.value) {
        step.status = "ready";
    }
    for (const step of steps.value) {
        if (step.checked) {
            runStepsStatus.value = true;
            try {
                let responseData = await runStep(step, false);
                responseBody.value += responseData.logs;
                if (responseData.status == "error") {
                    runStepsStatus.value = false;
                    logDrawer.value = true;
                    return;
                }
            } catch (e) {
                console.log(e);
            }
        }
    }
    if (runStepsStatus.value == false) {
        popupError("没有选中任何步骤");
    } else {
        logDrawer.value = true;
    }

    runStepsStatus.value = false;
};

/**
 * 运行测试用例
 *
 * @returns 无返回值
 */
const runCase = () => {
    if (
        yamlOutPath.value == "" ||
        compileCommand.value == "" ||
        caseOutPath.value == ""
    ) {
        popupError("输出路径或编译命令为空，请输入相关配置");
        configDrawer.value = true;
        return;
    }

    if (fileName.value == "") {
        popupError("文件名不能为空");
        return;
    }
    if (serverStauts.value != "running") {
        popupError("请确认是否启动服务");
        configDrawer.value = true;
        return;
    }

    caseLoading.value = true;
    for (let i = 0; i < steps.value.length; i++) {
        let step = steps.value[i];
        let msg = checkCase(step);
        if (msg != "") {
            popupError(msg + "步骤：" + (i + 1));
            caseLoading.value = false;
            return;
        }
    }

    let data = {
        steps: steps.value,
        config: config.value,
        yamlDir: yamlOutPath.value,
        caseDir: caseOutPath.value,
        fileName: fileName.value + ".yaml",
        cmd: compileCommand.value,
    };
    axios
        .post(`${baseUrl.value}/runcase`, data, {
            headers: { "Content-Type": "application/json" },
        })
        .then((res) => {
            if (res.data.status == "success") {
                popupSuss(res.data.message);
            } else {
                popupError(res.data.message);
            }
            responseBody.value = res.data.logs;
            logDrawer.value = true;
        })
        .catch((err) => {
            popupError("请确认是否启动服务");
        })
        .finally(() => {
            caseLoading.value = false;
        });
};

const runServe = () => {
    if (workPath.value == "") {
        popupError("请输入工程目录");
        return;
    }
    window.ipcRenderer.send("appToMain", {
        cmd: "run",
        workPath: workPath.value,
    });
};
window.ipcRenderer.on("mainToApp", (e, arg) => {
    let cmd = arg.cmd;
    if (cmd == "run" && arg.msg == "ok") {
        serverStauts.value = "starting";
        console.log("服务启动命令执行中");
    }
});

/**
 * 关闭用例执行会话
 *
 * @returns 无返回值
 */
const stopServer = () => {
    axios
        .get(`${baseUrl.value}/quit`)
        .then()
        .catch((err) => {
            console.log(err);
        });
    serverStauts.value = "stop";
};

const heartbeat = () => {
    setTimeout(() => {
        axios
            .get(`${baseUrl.value}/heartbeat`, { timeout: 1000 * 10 })
            .then((res) => {
                serverStauts.value = "running";
            })
            .catch((err) => {
                if (axios.isCancel(err)) {
                    console.log("Request canceled", err.message);
                } else {
                    // 处理其他错误
                }
                serverStauts.value = "stop";
            })
            .finally(() => {
                heartbeat();
            });
    }, 5000);
};
heartbeat();
/**
 * 关闭用例执行会话
 *
 * @returns 无返回值
 */
const closeSession = () => {
    axios
        .post(
            `${baseUrl.value}/closeSession`, // 替换为您的目标 API 端点
            {
                timeout: 5000, // 设置超时时间为 5000 毫秒（5 秒）
                headers: {
                    "Content-Type": "application/json", // 如果后端需要 JSON 格式的数据，请设置此头部
                },
            }
        )
        .then((res) => {
            if (res.data.message) {
                popupSuss(res.data.message);
            } else {
                popupSuss(res.data.message);
            }
        })
        .catch((res) => {
            popupError("请启动服务端");
            configDrawer.value = true;
        });
    steps.value.forEach((step) => {
        step.status = "ready";
    });
};

/**
 * 更新用例配置
 *
 * @returns 无返回值
 */
const updateConfig = () => {
    let msg = checkCase(steps.value[0]);
    if (msg != "") {
        popupError(msg);
        return;
    }
    axios
        .post(`${baseUrl.value}/updateConfig`, JSON.stringify(config.value), {
            headers: { "Content-Type": "application/json" },
        })
        .then((res) => {
            if (res.data.status == "success") {
                popupSuss(res.data.message);
            } else {
                popupError(res.data.message);
            }
        })
        .catch((error) => {
            popupError("确认是否启动服务");
        });
};

/**
 * 检查测试用例信息是否完整
 *
 * @param step 测试步骤对象
 * @returns 若有信息缺失则返回相应的提示信息，否则返回空字符串
 */
const checkCase = (step) => {
    if (config.value.name == "") {
        return "请输入测试用例名称";
    }
    if (config.value.base_url == "") {
        return "请输入测试域名";
    }
    if (step.name == "") {
        return "请输入测试步骤名称";
    }
    if (step.request.url == "") {
        return "请输入测试接口地址";
    }
    return "";
};

/**
 * 下载YAML用例文件
 *
 * @returns 无返回值
 */
const downloadYaml = () => {
    if (serverStauts.value != "running") {
        popupError("请确认是否启动服务");
        configDrawer.value = true;
        return;
    }
    for (let i = 0; i < steps.value.length; i++) {
        let step = steps.value[i];
        let msg = checkCase(step);
        if (msg != "") {
            popupError(msg + "步骤：" + (i + 1));
            caseLoading.value = false;
            return;
        }
    }
    if (yamlOutPath.value == "") {
        popupError("请选择输出路径");
        configDrawer.value = true;
        return;
    }
    if (fileName.value == "") {
        popupError("请输入文件名");
        return;
    }
    let data = {
        steps: steps.value,
        config: config.value,
        yamlDir: yamlOutPath.value,
        caseDir: caseOutPath.value,
        fileName: fileName.value + ".yaml",
    };

    axios
        .post(
            `${baseUrl.value}/downloadYaml`, // 替换为您的目标 API 端点
            JSON.stringify(data),
            {
                timeout: 5000, // 设置超时时间为 5000 毫秒（5 秒）
                headers: {
                    "Content-Type": "application/json", // 如果后端需要 JSON 格式的数据，请设置此头部
                },
            }
        )
        .then((res) => {
            if (res.data.status == "success") {
                popupSuss("输出成功");
            } else {
                popupError(res.data.message);
            }
        })
        .catch((error) => {
            popupError("请启动服务端");
        });
};

/**
 * 向列表中添加一个步骤对象
 *
 * @param list 步骤列表
 * @returns 无返回值
 */
const addStep = (list) => {
    list.push({
        name: "",
        setup_hooks: [],
        request: {
            url: "",
            method: "POST",
            headerList: [],
            cookieList: [],
            paramList: [{ name: "", value: "" }],
            dataList: [{ name: "", value: "" }],
            json: "",
        },
        teardown_hooks: [],
        variableList: [],
        extractList: [],
        validateList: [],
        paramRadio: 2,
        status: "ready",
        isDraggable: true,
        checked: false,
    });
};

const copyStep = (steps, index) => {
    steps.splice(index + 1, 0, JSON.parse(JSON.stringify(steps[index])));
};

/**
 * 向列表中添加一个参数对象
 *
 * @param list 列表数组
 * @returns 无返回值，直接修改传入的列表
 */
const addParam = (list) => {
    list.push({ name: "", value: "" });
};

/**
 * 从列表中删除指定索引位置的元素
 *
 * @param list 要删除元素的列表
 * @param index 要删除元素的索引位置
 * @returns 无返回值，直接修改原列表
 */
const delParam = (list, index) => {
    list.splice(index, 1);
};

/**
 * 向数组配置中新增一项
 *
 * @param list 要添加空字符串的数组。
 * @returns 无返回值。
 */
const addArr = (list) => {
    list.push("");
};

/**
 * 添加验证规则
 *
 * @param list 验证规则列表
 * @returns 无返回值
 */
const addValidate = (list) => {
    list.push({ funcName: "eq", actual: "", expected: "", msg: "" });
};
</script>

<style>
#app {
    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 10px;
}
.collapse-main {
    margin-top: 50px;
}
.header {
    margin-right: 40px;
    margin-bottom: 20px;
    position: fixed;
    z-index: 999;
    top: 8px;
    left: 8px;
}
.timestamp {
    color: #008000;
}

.logs {
    text-align: left;
    white-space: pre-wrap;
}

.log-info {
    color: #000000;
}

.log-debug {
    color: #1844c9; /* 调试级别日志颜色 */
}

.log-error {
    color: #e3402d; /* 错误级别日志颜色 */
}

.log-warn {
    color: #ffa500; /* 警告级别日志颜色 */
}
.but-item {
    display: flex;
    justify-content: center; /* 水平居中 */
    align-items: center; /* 垂直居中 */
    margin-right: 5px;
}
.checkbox {
    display: flex;
    justify-content: center; /* 水平居中 */
    align-items: center; /* 垂直居中 */
    margin-right: 15px;
    margin-left: 5px;
}
.params {
    flex-direction: column;
    width: 500px;
    margin-bottom: 5px;
}

.button-top {
    width: 300px;
    display: flex;
    flex-direction: column;
    margin-top: 10px;
}
.collapse-item {
    max-width: 1000px;

    display: flex;
}
.button-container {
    display: flex;
}

.collapse-item-container {
    width: 700px;
    min-width: 500px;
}
.collapse-item-container .el-collapse-item__header {
    margin-bottom: 5px;
    border-radius: 5px;
    white-space: nowrap; /* 防止文本换行 */
    overflow: hidden; /* 隐藏超出容器的内容 */
    text-overflow: ellipsis; /* 超出部分用省略号表示 */
    background-color: #f0f0f0;
}
.select-width {
    width: 240px;
}
li {
    list-style-type: none;
}
.li-item {
    margin-bottom: 5px;
}

.item {
    display: flex;
    width: 340px;
    margin-bottom: 5px;
}
.list {
    width: 700px;
    margin-bottom: 10px;
}
.left {
    display: flex !important;
    justify-content: flex-start !important;
}
.right {
    margin-right: 5px;
    display: flex;
    justify-content: flex-end;
}
.title {
    align-items: center;
    width: 100px;
    font-size: 15px;
    margin-bottom: 5px;
}
</style>
